package AG;

import samples.AG_Generated;
import core.AgentInfo;
import core.DominoServer;

public class DNA implements Comparable<DNA>{
	
	private static final int GENES = 14;
	private static final double MUTATION_RATIO = 0.2;
	private double[] DNACode;
	private double evaluation = -1.0;

	
	public DNA() {
		DNACode = new double[GENES];
		for (int i = 0; i < DNACode.length; i++) {
			DNACode[i] = Math.random();
		}
	}
	
	public DNA(double[] DNACode) {
		this.DNACode = DNACode;
	}
	
	@Override
	public int compareTo(DNA o) {
		return (this.evaluateDNA()-o.evaluateDNA()) < 0 ? 1 : -1;
		//maiores na frente
	}
	
	public double evaluateDNA() {
		if (evaluation>0.0)
			return evaluation;
		
			DominoServer dm = DominoServer.getInstance();
			dm.loadAgents();
			AgentInfo a = new AgentInfo("AG_Generated", new  AG_Generated(this));
			dm.addAgent(a);
			dm.start();
			evaluation = a.getStatistics().getVictoryCount();
		return evaluation;
	}
	public double getGene(int i) {
		return DNACode[i];
	}
	
	public void mutate() {
		for (int i = 0; i < GENES; i++) {
			if (Math.random() <= MUTATION_RATIO) {
				if (Math.random()>0.5) {
					DNACode[i] *= 1.1;
				} else {
					DNACode[i] *= 0.9;
				}
			}
		}
	}

	//ATENCAO a.reproduce(b) != b.reproduce(a)
	public DNA reproduce(DNA other) {
		DNA child = new DNA();
		int k = (int) (Math.random()*((double)GENES));
		for (int i = 0; i < k; i++) {
			child.DNACode[i] = this.DNACode[i];
		}
		for (int i = k ; i < GENES; i++) {
			child.DNACode[i] = other.DNACode[i];
		}
		return child;
	}
	
	@Override
	public String toString() {
		String out = "";
		for (double gene : DNACode) {
			out+=gene + " ";
		}
		return out;
	}
	
	@Override
	public boolean equals(Object o) {
		if (o instanceof DNA) {
			DNA dna = (DNA) o;
			for (int i = 0 ; i < GENES ; i++) {
				if (((dna.DNACode[i] - this.DNACode[i]) > 0.000001) || ((this.DNACode[i] - dna.DNACode[i]) > 0.000001)) {
					return false;
				}
			}
			return true;
		}
		return false;
	}
}
